package com.ai.bitcoin.schedule.task;

import com.ai.bitcoin.constant.Bcc;
import com.ai.bitcoin.jpa.entity.BccBatch;
import com.ai.bitcoin.jpa.entity.BccDailyInfo;
import com.ai.bitcoin.jpa.entity.BccDailyInfoCrawl;
import com.ai.bitcoin.jpa.entity.BccDailyInfoHis;
import com.ai.bitcoin.jpa.service.*;
import com.ai.bitcoin.serialize.BeanSerial;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * @author Jason
 * @date 2018/3/29
 **/
@Slf4j
@Component
public class DailyInfoTask extends AbstractTask {
    @Autowired
    BccScoreRuleService bccScoreRuleService;
    @Autowired
    BccDailyInfoCrawlService bccDailyInfoCrawlService;
    @Autowired
    BccBatchService bccBatchService;
    @Autowired
    BccRankHisService BccRankHisService;
    @Autowired
    BccDailyInfoService bccDailyInfoService;
    @Autowired
    BccDailyInfoHisService bccDailyInfoHisService;


    @Override
    public void execute() {
        long start;
        List<BccBatch> dailyBatchList = bccBatchService.findByBatchTypeAndBatchStateOrderByBatchTimeEndDesc(Bcc.BathType.CRAWL_DAILY_INFO, Bcc.BathState.CRAWL_DONE);
        if (dailyBatchList.size() == 0) {
            log.info("爬虫太慢了还没有新批次数据");
            return;
        }
        BccBatch latestBccBatch = dailyBatchList.get(0);
        if (dailyBatchList.size() > 1) {
            log.info("爬虫爬取数据真快呀，我都错过了{}个版本了,把这些版本状态更新为:{}", dailyBatchList.size() - 1, Bcc.BathState.EXPIRE);
            for (int i = 1; i < dailyBatchList.size(); i++) {
                BccBatch bccBatch = dailyBatchList.get(i);
                bccBatch.setBatchState(Bcc.BathState.EXPIRE);
                log.info("", BeanSerial.Bean2Json(bccBatch).toString());
                bccBatchService.save(bccBatch);
            }
        }

        String latestBatchNo = latestBccBatch.getBatchNo();
        if (StringUtils.isEmpty(latestBatchNo)) {
            log.info("糟糕，batch为空，不能执行,{}", BeanSerial.Bean2Json(latestBccBatch).toString());
            return;
        }

        log.info("开始评级处理，batchNo:{}", BeanSerial.Bean2Json(latestBccBatch).toString());
        BccBatch updateDailyInfoBatch = CommonUtil.getBatchNo(latestBatchNo);

        log.info("清理未发布的脏数据");
        start = System.currentTimeMillis();
        bccDailyInfoService.deleteNoPublish();
        log.info("清理未发布的脏数据，consume:{}ms", (System.currentTimeMillis() - start));

        log.info("开始将爬取的数据入库到bcc_daily_info表");
        start = System.currentTimeMillis();
        Sort sort = new Sort(Sort.Direction.ASC, "bccId");
        Pageable pageable = PageRequest.of(0, pageSizeDb, sort);
        Page<BccDailyInfoCrawl> page = bccDailyInfoCrawlService.findByBatchNo(latestBatchNo, pageable);
        List<BccDailyInfoCrawl> bccDailyInfoCrawls = page.getContent();

        int pageNum = page.getTotalPages();
        log.info("总共页数:{},每页大小:{}", pageNum, pageSizeDb);

        for (int i = 0; i < pageNum; i++) {
            if (i != 0) {
                pageable = PageRequest.of(i, pageSizeDb, sort);
                page = bccDailyInfoCrawlService.findByBatchNo(latestBatchNo, pageable);
                bccDailyInfoCrawls = page.getContent();
            }
            saveList2Info(bccDailyInfoCrawls);
        }

        log.info("爬取的数据入库到bcc_daily_info表结束，consume:{}ms", (System.currentTimeMillis() - start));

        log.info("save to daily_info_his");
        save2DailyInfoHis();

        log.info("开始换版,batchNo:{}", latestBatchNo);
        start = System.currentTimeMillis();
        bccDailyInfoService.update2Publish(latestBatchNo);
        log.info("换版完成，consume:{}ms", (System.currentTimeMillis() - start));

        //更新批次状态
        log.info("更新批次状态,bath={},{}->{}", latestBatchNo, Bcc.BathState.CRAWL_DONE, Bcc.BathState.HANDLE_DONE);
        latestBccBatch.setBatchState(Bcc.BathState.HANDLE_DONE);
        bccBatchService.save(latestBccBatch);

        log.info("创建批次：{}", BeanSerial.Bean2Json(updateDailyInfoBatch));
        updateDailyInfoBatch.setBatchTimeEnd(new Date());
        bccBatchService.save(updateDailyInfoBatch);
    }

    @Transactional
    public void save2DailyInfoHis() {
        List<BccDailyInfo> list = bccDailyInfoService.findByRecordState(Bcc.RecordState.PUBLISH);
        for (BccDailyInfo bccDailyInfo : list) {
            BccDailyInfoHis bccDailyInfoHis = new BccDailyInfoHis();
            BeanUtils.copyProperties(bccDailyInfo, bccDailyInfoHis);
            bccDailyInfoHisService.save(bccDailyInfoHis);
        }
    }

    @Transactional
    public void saveList2Info(List<BccDailyInfoCrawl> list) {
        if (list.size() == 0) {
            return;
        }
        for (BccDailyInfoCrawl aList : list) {
            BccDailyInfo bccDailyInfo = new BccDailyInfo();
            String bccId = aList.getBccId();
            if (StringUtils.isEmpty(bccId)) {
                continue;
            }
            BeanUtils.copyProperties(aList, bccDailyInfo);
            bccDailyInfo.setId(UUID.randomUUID().toString());
            bccDailyInfo.setRecordState(Bcc.RecordState.UN_PUBLISH);
            log.info("bccId:{}", bccDailyInfo.getBccId());
            bccDailyInfoService.save(bccDailyInfo);
        }
    }

}
